/**
 * vueRouteUtil工具类
 * Created by 超级小富翁 on 2017/5/9.
 */

/**
 * 路由工具
 */
function vueRouteUtil() {
	var vueRouteUtil = {
		addRouteByNamedView: function(item) {
			var urlParamsName = "/:urlParams";
			// 检查路由信息是否添加，解决性能问题
			if($indexScope.addedRouteInfo.indexOf(item.name) == -1) {
				$indexScope.addedRouteInfo.push(item.name);
				// 初始化当前需要添加到vue-route的路由
				$indexScope.routeInfo = [];
				// 添加一个标识点，阻断中间由于流程未走完就添加路由导致页面无法显示的问题
				$indexScope.loadComponentFlag++;
				// 第一次默认加载默认模板
				vueRouteUtil.loadComponent(item, item.name, function(contentComponent) {
					var routeInfo = {
						name: item.name,
						path: item.routePath + urlParamsName,
						components: {
							default: contentComponent
						},
						children: []
					};
					$indexScope.routeInfo.push(routeInfo);
					loadParentHtmlComponent(item);
				});
				$indexScope.loadComponentFlag--;

				/**
				 * 传入vueRouteFilePath中的配置，依次加载父页面，加载完毕后调用加载子页面的方法
				 * @param {Object} itemPageInfo
				 * @param {Object} params
				 */
				function loadParentHtmlComponent(itemPageInfo, params) {
					if(params == null) {
						params = {
							currentRoutePath: itemPageInfo.routePath
						};
					}
					if(itemPageInfo.parentPage != null && itemPageInfo.parentPage != '') {
						// 递归加载父页面，加载完毕自动进入加载子页面流程
						var parentPageInfo = $indexScope.routeFilePath[itemPageInfo.parentPage];
						if(parentPageInfo == undefined) {
							console.error(itemPageInfo.name + " 父页面配置没有找到：" + itemPageInfo.parentPage);
						} else {
							vueRouteUtil.loadComponent(parentPageInfo, parentPageInfo.name, function(contentComponent) {
								$indexScope.routeInfo = [{
									name: parentPageInfo.name,
									path: params.currentRoutePath + urlParamsName,
									components: {
										default: contentComponent
									},
									children: $indexScope.routeInfo
								}];
								loadParentHtmlComponent(parentPageInfo, params);
							});
						}
					} else {
						// 父页面加载完毕，开始加载子页面
						loadChildrenHtmlComponent($indexScope.routeInfo, null, params);
					}
				}

				/**
				 * 传入路由信息去加载每一个路由的子页面
				 * @param {Object} currentRouteInfo
				 * @param {Object} params
				 */
				function loadChildrenHtmlComponent(currentRouteInfo, itemPageInfo, params) {
					if(itemPageInfo == null) {
						itemPageInfo = $indexScope.routeFilePath[currentRouteInfo[0].name];
					}
					// 判断当前页面配置是否有子页面
					if(itemPageInfo.childrenPage != null && itemPageInfo.childrenPage.length > 0) {
						loadChildrenPageInfo(0);
						// 加载子模板页面
						function loadChildrenPageInfo(i) {
							if(i < itemPageInfo.childrenPage.length) {
								// 获取子页面配置
								var childConfig = itemPageInfo.childrenPage[i];
								// 获取子页面配置信息
								var childPageInfo = $indexScope.routeFilePath[childConfig.configName];
								vueRouteUtil.loadComponent(childPageInfo, childConfig.configName, function(contentComponent) {
									if(currentRouteInfo[0].children == null || currentRouteInfo[0].children.length == 0) {
										currentRouteInfo[0].children.push({
											name: childPageInfo.name,
											path: params.currentRoutePath + urlParamsName,
											components: {},
											children: []
										});
									}
									if(childConfig.defaultChildPage == 1) {
										if(currentRouteInfo[0].children[0].components.default == null)
											currentRouteInfo[0].children[0].components.default = contentComponent;
									} else {
										currentRouteInfo[0].children[0].components[childConfig.routerViewName] = contentComponent;
									}
									// 判断子页面是否存在子页面
									if(childPageInfo.childrenPage != null && childPageInfo.childrenPage.length > 0) {
										loadChildrenHtmlComponent(currentRouteInfo[0].children, childPageInfo, params);
									}
									loadChildrenPageInfo(++i);
								});
							}
						}
					}
					// 判断当前下一个节点是否存在元素
					if(currentRouteInfo[0].children.length > 0) {
						loadChildrenHtmlComponent(currentRouteInfo[0].children, null, params);
					}
				}
			} else {
				$indexScope.closeLoading();
			}
		},
		/**
		 * 更具网络地址加载vue模板
		 * @param {Object} vueRouteFileConfig vueRouteFilePath配置里面的元素
		 * @param {Object} itemName 加载的名称
		 * @param {Object} successFun 加载成功的回调方法
		 */
		loadComponent: function(vueRouteFileConfig, itemName, successFun) {
			if(!$indexScope.routeFilePath[itemName]) {
				console.log("当前配置不存在：" + itemName);
			} else if($indexScope.routeFilePath[itemName].component == null) {
				$indexScope.loadComponentFlag++;
				// 加载对应css样式
				if(vueRouteFileConfig.cssFile == 1) {
					require(['lib/require/css!' + vueRouteFileConfig.filePath], function(css) {});
				}
				// 加载需要用到的模板
				if(vueRouteFileConfig.componentConfig && vueRouteFileConfig.componentConfig.length > 0) {
					for(var index = 0; index < vueRouteFileConfig.componentConfig.length; index++) {
						$indexScope.loadComponentByName(vueRouteFileConfig.componentConfig[index]);
					}
				}
				// 加载模板文件html和js
				require(['lib/require/text!' + vueRouteFileConfig.filePath + '.html', vueRouteFileConfig.filePath], function(html, js) {
					try {
						js.template = html;
					} catch(e) {
						js = {
							template: html
						};
					}
					$indexScope.routeFilePath[itemName].component = js;
					successFun(js);
					$indexScope.routeFilePath[itemName].component.created = function() {
						$indexScope.currentRouteScope[itemName] = this;
					};
					$indexScope.loadComponentFlag--;
				});
			} else {
				$indexScope.loadComponentFlag++;
				successFun($indexScope.routeFilePath[itemName].component);
				$indexScope.loadComponentFlag--;
			}
		}
	};
	return vueRouteUtil;
}

/**
 * 初始化路由
 */
var vueRouter = new VueRouter({
	routes: [{
		path: '/',
		components: {
			default: {
				template: '<div>未载入模板或没有权限，请刷新页面<router-view name="header"></router-view><router-view></router-view><router-view name="footer"></router-view></div>'
			}
		},
		children: [{
			path: '/',
			components: {
				default: {
					template: '<div>未载入模板或没有权限<router-view name="header1"></router-view><router-view></router-view><router-view name="footer1"></router-view></div>'
				},
				header: {
					template: '<div>头部</div>'
				},
				footer: {
					template: '<div>尾部</div>'
				}
			}
		}]
	}]
});

/** 全局控制 **/
var $indexScope = new Vue({
	router: vueRouter,
	el: '#indexPage',
	store: $rootScope,
	data: {
		userInfo: $rootScope.state.userInfo,
		// 当前路由信息
		routeInfo: [],
		// 已添加的路由路径
		addedRouteInfo: [],
		// 路由加载的标识，用于解决路由模板未加载完就添加路由的情况
		loadComponentFlag: 0,
		// 配置路由和文件路径信息
		routeFilePath: {},
		// 模板文件路径信息
		componentFilePath: {},
		// 默认的调转页面
		defaultGoPage: '/',
		// 是否存在加载层
		hasLoading: false,
		// 默认延迟加载层的在成功调用后延迟关闭的毫秒数，建议值：400
		defaultCloseLoadingSeconds: 400,
		// 需要预加载的css列表，如果为相对路径，则为index.html的相对路径
		cssFiles: [],
		// 需要预加载的js列表，如果为相对路径，则为index.html的相对路径，为了解决依赖问题默认加载的js文件路径
		jsFiles: [],
		// 默认配置文件路径
		defaultConfigFileUrl: "js/config-json/vueIndexConfig.json",
		// 默认路由文件路径
		defaultRouteFilePathUrl: [],
		// 默认组件配置文件路径
		defaultVueComponentsConfigUrl: [],
		// 网络请求参数
		urlParams: {},
		// 当前路由的所有模板域
		currentRouteScope: {},
		// 开发模式
		developmentMode: 0
	},
	watch: {
		userInfo: {
			handler: function(val, oldVal) {
				sessionStorage.setItem('userInfo', JSON.stringify(this.userInfo));
			},
			deep: true
		},
		// 监听路由加载的标识，当该值被归零的时候添加路由
		loadComponentFlag: {
			handler: function(val, oldVal) {
				if(val == 0) {
					//console.log($indexScope.routeInfo);
					//console.log($indexScope.addedRouteInfo);
					vueRouter.addRoutes($indexScope.routeInfo);
					$indexScope.closeLoading();
				}
			},
			deep: true
		}
	},
	// 方法
	methods: {
		// 前往默认页面
		goDefaultPage: function() {
			this.goPage(this.defaultGoPage);
		},
		// 打开加载层，默认为layer中2的效果，可取值：0、1、2
		openLoading: function(type) {
			if(this.hasLoading == false) {
				layer.load(type == null ? 2 : type);
				this.hasLoading = true;
			}
		},
		// 关闭加载层，time：关闭加载层的时间，默认为0单位毫秒
		closeLoading: function(time) {
			var thisx = this;
			if(this.hasLoading == true) {
				setTimeout(function() {
					layer.closeAll('loading'); //关闭加载层
					thisx.hasLoading = false;
				}, time == null ? thisx.defaultCloseLoadingSeconds : time);
			}
		},
		// 加载默认配置文件
		loadDefaultConfig: function() {
			$.getJSON($indexScope.defaultConfigFileUrl, function(data) {
				for(var i = 0; i < data.length; i++) {
					$indexScope[data[i].key] = data[i].value;
				}
				// 递归添加路由文件信息
				eachLoadRouteFile(0);

				function eachLoadRouteFile(i) {
					if(i < $indexScope.defaultRouteFilePathUrl.length) {
						$.getJSON($indexScope.defaultRouteFilePathUrl[i], function(data) {
							$indexScope["routeFilePath"] = $indexScope.mergeObject($indexScope.routeFilePath, data);
							eachLoadRouteFile(++i);
						});
					} else {
						$indexScope.loadComponentFile();
						$indexScope.loadDefaultFile();
						if($indexScope.isDevelopmentMode()) {
							$rootScope.dispatch("setUserLogin");
						}
					}
				}
			});
		},
		// 加载默认文件，一般为css文件和js文件，采用异步加载，并调用框架默认加载方法
		loadDefaultFile: function() {
			var thisx = this;
			var loadFiles = [];
			for(var i = 0; i < this.cssFiles.length; i++) {
				loadFiles.push('lib/require/css!' + this.cssFiles[i]);
			}
			loadJSFiles(0);
			// 按照顺序去加载js文件，解决了依赖加载问题
			function loadJSFiles(j) {
				if(j < thisx.jsFiles.length) {
					require([thisx.jsFiles[j]], function() {
						loadJSFiles(++j);
					});
				} else {
					require(loadFiles);
					thisx.defaultFun();
				}
			}
		},
		// 通过递归加载组件
		loadComponentFile: function() {

			// 递归加载vue组件配置文件
			eachLoadVueComponentsConfigFile(0);

			function eachLoadVueComponentsConfigFile(i) {
				if(i < $indexScope.defaultVueComponentsConfigUrl.length) {
					$.getJSON($indexScope.defaultVueComponentsConfigUrl[i], function(data) {
						$indexScope["componentFilePath"] = $indexScope.mergeObject($indexScope.componentFilePath, data);
						eachLoadVueComponentsConfigFile(++i);
					});
				} else {
					var keys = [];
					for(var key in $indexScope.componentFilePath) {
						keys.push(key);
					}
					eachLoadComponentFile(0);
					// 通过递归加载组件
					function eachLoadComponentFile(index) {
						if(index < keys.length) {
							if($indexScope.componentFilePath[keys[index]].initLoad == 1) {
								$indexScope.loadComponentByName($indexScope.componentFilePath[keys[index]].configName);
							}
							eachLoadComponentFile(++index);
						}
					}
				}
			}
		},
		// 传入需要加载组件的name来加载vue组件
		loadComponentByName: function(configName, successFun) {
			var vueComponentFileConfig = $indexScope.componentFilePath[configName];
			if(!vueComponentFileConfig) {
				console.log("当前模板配置不存在：" + configName);
			} else if(!vueComponentFileConfig.component) {
				if(vueComponentFileConfig.cssFile == 1) {
					require(['lib/require/css!' + vueComponentFileConfig.filePath], function(css) {});
				}
				Vue.component(vueComponentFileConfig.componentName, function(resolve, reject) {
					require(['lib/require/text!' + vueComponentFileConfig.filePath + '.html', vueComponentFileConfig.filePath], function(html, js) {
						try {
							js.template = html;
						} catch(e) {
							js = {
								template: html
							};
						}
						$indexScope.componentFilePath[configName].component = js;
						// 向 `resolve` 回调传递组件定义
						resolve(js);
						if(typeof successFun == "function") {
							successFun(vueComponentFileConfig, js);
						}
					});
				});
			}
		},
		// 加载框架时的默认方法
		defaultFun: function() {
			var path = $indexScope.$route.path;
			if(path.substring(1).indexOf('/') > 0) {
				path = path.substring(1, path.substring(1).indexOf('/') + 1);
			} else {
				path = path.substring(1);
			}
			// 加载首页并进入默认页面
			if($indexScope.$route.path.substring(1) != '' && $indexScope.routeFilePath[path] != undefined) {
				vueRouteUtil().addRouteByNamedView($indexScope.routeFilePath[path]);
			} else {
				$indexScope.goDefaultPage();
			}
		},
		// 跳转路径的方法
		goPage: function(path, params) {
			params = !params ? {} : params;
			if(path.indexOf('/') == 0) {
				this.$router.push(path + "/" + JSON.stringify(params));
			} else {
				this.$router.push('/' + path + "/" + JSON.stringify(params));
			}
		},
		// 这个方法的参数是一个整数，意思是在 history 记录中向前或者后退多少步，类似 window.history.go(n)。
		goHistory: function(n) {
			this.$router.go(n);
		},
		/**
		 * @param {Object} urlName 请求接口的名称，因对应后台制定的规则
		 * @param {Object} params 请求需要发送时需要携带的参数
		 * @param {Object} successCallback 成功调用时返回的回调函数，传入两个值，data：后台放回的数据；response：请求返回的所有信息
		 * @param {Object} errorCallback 失败调用时返回的回调函数，传入两个值，data：后台放回的数据；response：请求返回的所有信息
		 * @param {Object} optionsParams 自定义的vue-resource中的options参数
		 * optionsParams自定义参数
		 * projectPath：网络路径的网络套接字前段， 当不为null时就会去拼接
		 * suffix：自定义的后缀名， 当不为null时就会去拼接
		 * method：自定义请求方法：GET、POST、JSONP
		 * tiemout：自定义超时时间，当为不小于零的数字的时候使用
		 * emulateJSON：默认设置为启用，当为0的时候则关闭；启用该选项后，请求会以application/x-www-form-urlencoded作为MIME type，就像普通的HTML表单一样
		 * credientials：默认设置为启用，当为0的时候则关闭；跨域请求时是否需要使用凭证
		 */
		httpSend: function(url, params, successCallback, errorCallback, optionsParams) {
			optionsParams = optionsParams == null ? {} : optionsParams;
			if(optionsParams.projectPath == null) {
				url = $indexScope.urlParams.projectPath + url;
			} else {
				url = optionsParams.projectPath + url;
			}
			if(optionsParams.suffix == null) {
				url += $indexScope.urlParams.suffix;
			} else {
				url += optionsParams.suffix;
			}
			// 拼装参数
			var options = {
				url: url,
				// 默认为：0，单位为 ms。表示请求超时时间。0表示没有超时限制。超时后，将会取消当前请求。
				timeout: optionsParams.tiemout != null && typeof optionsParams.tiemout == 'number' &&
					optionsParams.tiemout >= 0 ? optionsParams.tiemout : $indexScope.urlParams.defaultTiemout
			};
			if(!optionsParams.method) {
				options.method = $indexScope.urlParams.defaultMethod;
			} else if(optionsParams.method.toUpperCase() == "POST") {
				options.method = "POST";
			} else if(optionsParams.method.toUpperCase() == "JSONP") {
				options.method = "JSONP";
			} else if(optionsParams.method.toUpperCase() == "GET") {
				options.method = "GET";
			} else {
				options.method = $indexScope.urlParams.defaultMethod;
			}
			if(options.method == 'POST') {
				options.body = params;
			} else {
				options.params = params;
			}
			if(optionsParams.emulateJSON != 0) {
				// 启用该选项后，请求会以application/x-www-form-urlencoded作为MIME type，就像普通的HTML表单一样
				options.emulateJSON = true;
			}
			if(optionsParams.credentials != 0) {
				// 跨域请求时是否需要使用凭证
				options.credentials = true;
			}
			// 发送请求
			Vue.http(options).then(function(response) {
				if(typeof successCallback == 'function') {
					if(!$indexScope.urlParams.successConditions.field) {
						successCallback(response.data, response);
					} else {
						if(response.data[$indexScope.urlParams.successConditions.field] == $indexScope.urlParams.successConditions.value) {
							successCallback(response.data, response);
						} else if(typeof errorCallback == 'function') {
							errorCallback(response.data, response);
						} else if(response.data[$indexScope.urlParams.msgTipField]) {
							alertModule().alertMsg(response.data[$indexScope.urlParams.msgTipField]);
						}
					}
				}
			}, function(response) {
				if(typeof errorCallback == 'function') {
					errorCallback(response.data, response);
				}
				if(response.status == 0) {
					alertModule().msg("网络连接失败，请检查网络连接或者服务器已经挂掉了");
				}
			});
		},
		// 文件下载
		fileDownload: function(id) {
			var url = $indexScope.urlParams.projectPath + "file/" + id + $indexScope.urlParams.suffix;
			var a = document.createElement("a"); //创建a标签
			var e = document.createEvent("MouseEvents"); //创建鼠标事件对象
			e.initEvent("click", false, false); //初始化事件对象
			a.href = url; //设置下载地址
			a.dispatchEvent(e); //给指定的元素，执行事件click事件
		},
		// 获取当前路由的参数
		getRouterParams: function() {
			try {
				return JSON.parse(this.$route.params.urlParams);
			} catch(e) {
				return {};
			}
		},
		// 是否处于开发模式
		isDevelopmentMode: function() {
			if(this.developmentMode == 1) {
				return true;
			} else {
				return false;
			}
		},
		/**
		 * 合并对象，将两个对象合并成一个对象，当存在相同属性的时候会保留第二个对象的值
		 * @param {Object} obj1
		 * @param {Object} obj2
		 */
		mergeObject: function(obj1, obj2) {
			for(var key in obj2) {
				if(obj1.hasOwnProperty(key)) {
					console.error("合并过程中找到相同属性：" + key + "，第一个对象中的值：" + obj1[key] + "，第二个对象中的值：" + obj2[key]);
				}
				obj1[key] = obj2[key];
			}
			return obj1;
		}
	},
	mounted: function() {
		this.openLoading();
		$indexScope = this;
		// 检查sessionStorage中是否发现用户信息
		try {
			$rootScope.dispatch('setUserLogin', JSON.parse(sessionStorage.getItem('userInfo')));
		} catch(e) {
			console.log('sessionStorage中未发现已登录的用户信息');
		}
		// 路由监听
		vueRouter.beforeEach(function(to, from, next) {
			$indexScope.openLoading();
			if(to.fullPath == from.fullPath) {
				next();
			} else {
				var name = '';
				if(to.fullPath.substring(1).indexOf('/') > 0) {
					name = to.fullPath.substring(1, to.fullPath.substring(1).indexOf('/') + 1);
				} else {
					name = to.fullPath.substring(1);
				}
				// 检查访问的页面是否需要登录才能访问，有可能出现异常，暂未处理
				try {
					if($indexScope.routeFilePath[name] != null && $indexScope.routeFilePath[name].login == 1 && $indexScope.defaultGoPage == to.fullPath) {
						alertModule().msg('当前路径为默认页面的路径，不能设置为需要登录才能访问，请修改配置');
					}
					if(to.fullPath != '/' && $indexScope.defaultGoPage != to.fullPath && $indexScope.routeFilePath[name].login == 1) {
						$rootScope.commit('checkLoginUser', function() {
							goPathPage();
						});
					} else {
						goPathPage();
					}
				} catch(e) {
					$indexScope.closeLoading();
					next('/');
				}

				function goPathPage() {
					if($indexScope.routeFilePath[name]) {
						console.log('发现模板：' + name);
						vueRouteUtil().addRouteByNamedView($indexScope.routeFilePath[name]);
						next();
					} else if(to.fullPath == '/') {
						console.log('未发现模板：' + name);
						next();
						$indexScope.closeLoading();
					} else {
						next('/');
						$indexScope.closeLoading();
					}
				}
			}
		});

		$indexScope.loadDefaultConfig();
	}
});